/*
 * Copyright 2008 Nordic Consulting & Development Company
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package pl.ncdc.web.login.client.service;

import pl.ncdc.web.login.client.Credentials;

import com.google.gwt.http.client.Request;
import com.google.gwt.http.client.RequestBuilder;
import com.google.gwt.http.client.RequestCallback;
import com.google.gwt.http.client.RequestException;
import com.google.gwt.http.client.Response;
import com.google.gwt.user.client.rpc.AsyncCallback;

/**
 *  HTTP version of Async Authentication Service.
 *  Service is used to authenticate in cocoon environment. It sends user login and password (using http post method)
 *  to special URL (loginURL) where cocoon invoke login action to authenticate. Respond from login URL should represent text
 *  value of AuthenticationResult.
 * <p>
 * Created on Jun 9, 2008
 *
 * @author hshsce
 * @version $Id: HttpRequestAuthenticationServiceAsync.java 174 2009-01-29 23:25:07Z hshsce $
 */
public class HttpRequestAuthenticationServiceAsync implements AuthenticationServiceAsync {

	private final String m_loginURL;

	private final String m_logoutURL;

	private final String m_uidParameter;

	private final String m_passwordParameter;

	/**
	 * @param loginURL - http login url
	 * @param logoutURL - http logout url
	 * @param uidParam - param name to send uid to login url
	 * @param passwordParam - param name to send password to login url
	 */
	public HttpRequestAuthenticationServiceAsync(final String loginURL, final String logoutURL, final String uidParameter, final String passwordParameter) {
		if (loginURL == null) {
			throw new IllegalArgumentException("loginURL cannot be null");
		}
		if (logoutURL == null) {
			throw new IllegalArgumentException("logoutURL cannot be null");
		}
		if (uidParameter == null) {
			throw new IllegalArgumentException("uidParameter cannot be null");
		}
		if (passwordParameter == null) {
			throw new IllegalArgumentException("passwordParameter cannot be null");
		}
		m_loginURL = loginURL;
		m_logoutURL = logoutURL;
		m_uidParameter = uidParameter;
		m_passwordParameter = passwordParameter;
	}

	/**
	 * @see pl.ncdc.web.login.client.service.AuthenticationServiceAsync#login(java.lang.String, java.lang.String, boolean, java.util.Map, com.google.gwt.user.client.rpc.AsyncCallback)
	 */
	public void login(final Credentials credentials, final AsyncCallback<AuthenticationResult> callback) {
		final RequestBuilder builder = new RequestBuilder(RequestBuilder.POST, m_loginURL);

		builder.setHeader("Content-type", "application/x-www-form-urlencoded");
		final String postData = m_uidParameter + "=" + credentials.getUid() + "&" + m_passwordParameter + "=" + credentials.getPassword();
		builder.setRequestData(postData);

		builder.setCallback(new RequestCallback() {
			public void onResponseReceived(final Request request, final Response response) {
				try {
					final AuthenticationResult result = AuthenticationResult.valueOf(response.getText());
					callback.onSuccess(result);
				} catch (final IllegalArgumentException e) {
					callback.onFailure(e);
				}
			}
			public void onError(final Request request, final Throwable exception) {
				callback.onFailure(exception);
			}
		});
		try {
			builder.send();
		} catch (final RequestException e) {
			callback.onFailure(e);
		}
	}

	/**
	 * @see pl.ncdc.web.login.client.service.AuthenticationServiceAsync#logout(com.google.gwt.user.client.rpc.AsyncCallback)
	 */
	public void logout(final AsyncCallback<Void> callback) {
		final RequestBuilder builder = new RequestBuilder(RequestBuilder.GET, m_logoutURL);
		builder.setCallback(new RequestCallback() {
			public void onResponseReceived(final Request request, final Response response) {
				callback.onSuccess(null);
			}
			public void onError(final Request request, final Throwable exception) {
				callback.onFailure(exception);
			}
		});
		try {
			builder.send();
		} catch (final RequestException e) {
			callback.onFailure(e);
		}
	}

    public void isAuthenticated(final AsyncCallback<Boolean> callback) {
        throw new UnsupportedOperationException();
    }

}
